import { useCallback, useMemo, useState } from "react"
import { TestPaperEntity, TestPaperQuestionEntity } from "../../../../../queries/test"
import { QuestionOptions } from "../../../../admin/question/QuestionModal"
import { classNames } from "primereact/utils"
import PaperContext from "./PaperContext"
import { Button } from "antd"
import { gql, useMutation } from "@apollo/client"
import gqlError from "../../../../../libs/gql-error"
import { useSearchParams } from "react-router"

type QuestionType = "SINGLE" | "MULTIPLE" | "JUDGE" | "FILL" | "ANSWER"
export interface QuestionData {
  type: QuestionType,
  children: TestPaperQuestionEntity[]
}
export type QuestionAnswers = {
  [key: number]: string
}
export type TestType = "practice" | "reading" | "answer"

const PushPaperMutation = gql`
  mutation PushPaper(
    $id: Int!,
    $data: String!
  ){
    pushPaper(
      id: $id,
      data: $data
    )
  }
`
interface PaperCardProps {
  dataSource: TestPaperQuestionEntity[],
  testType: TestType,
  paper: TestPaperEntity,
  title: string,
}
const PaperCard = ({
  dataSource,
  testType,
  paper,
  title
}: PaperCardProps) => {
  const texts = ["一", "二", "三", "四", "五"];
  const list = useMemo(() => {
    let i = 1;
    let j = -1;
    let position = 0;
    const array = ["SINGLE", "MULTIPLE", "JUDGE", "FILL", "ANSWER"].map((value => {
      const children = dataSource.filter(item => item.type === value).map((item) => {
        return {
          ...item,
          position: position++,
        }
      })
      if (!!children.length) j++
      return {
        ...QuestionOptions.find(item => item.value === value),
        children,
        index: i++,
        text: texts[j]
      }
    }))
    return array;
  }, [dataSource])
  const [searchParams, setSearchParams] = useSearchParams()
  const [pushPaper] = useMutation(PushPaperMutation, {
    onCompleted: () => {
      setSearchParams({
        ...searchParams,
        testType: "answer"
      })
    },
    onError: (error) => {
      gqlError(error)
    }
  })
  const [answers, setAnswers] = useState<QuestionAnswers>({})
  const [current, setCurrent] = useState(0)
  const currentItem = list.flatMap(item => item.children).find(item => item.position === current)
  const renderColor = useCallback((
    item: TestPaperQuestionEntity,
  ) => {
    let bgColor = "bg-gray-100"
    let textColor;
    //如果答题了
    if (!!answers[item.id]) bgColor = "bg-blue-100";

    // 出了答案
    if (testType === "answer") {
      if (answers[item.id] === item.answer) bgColor = "bg-green-400"
      else bgColor = "bg-red-400"
    }

    //指针指向
    if (current === item.position) {
      textColor = "text-blue-500 font-bold text-xl"
    }
    return classNames(bgColor, textColor)
  }, [answers, current, testType])
  const onNext = useCallback(() => {
    if (current === list.flatMap(item => item.children).length - 1) return
    setCurrent(current + 1)
  }, [current, list])
  const onPrev = useCallback(() => {
    if (current === 0) return
    setCurrent(current - 1)
  }, [current, list])
  const sumScore = useMemo(() => {
    return dataSource.reduce((acc, item) => {
      return acc + item.score
    }, 0)
  }, [answers, dataSource])

  const onFinish = useCallback(() => {
    const keys = Object.keys(answers)
    const data = JSON.stringify(keys.map(key => {
      return {
        id: parseInt(key),
        answer: answers[parseInt(key)]
      }
    }))
    pushPaper({
      variables: {
        id: paper.id,
        data
      }
    })
  }, [paper, answers])
  return (
    <div
      className="flex gap-2 p-2 bg-white"
    >
      <div className="w-60">
        <h1 className="px-5 text-2xl">
          答题卡 (分钟)
        </h1>
        {list.map(({
          label,
          children,
          index,
          text
        }) => {
          if (!children.length) return null
          return (
            <div
              key={index}
            >
              <h1
                className="text-xl"
              >
                {text}、{label}
              </h1>
              <div className="flex flex-wrap gap-1">
                {children.map((item) => {
                  return (
                    <div
                      key={item.id}
                      className={classNames(
                        "w-10 h-10 flex justify-center items-center border cursor-pointer",
                        renderColor(item)
                      )}
                      onClick={() => {
                        setCurrent(item.position)
                      }}
                    >
                      {item.position + 1}
                    </div>
                  )
                })}
              </div>
            </div>
          )
        })}
      </div>
      <div style={{
        width: "calc(100% - 240px)"
      }}>
        <div className="flex gap-2">
          <Button
            type="primary"
            onClick={onFinish}
          >
            提交试卷
          </Button>
          <h1 className="text-2xl">
            {title}
          </h1>
        </div>
        <div className="flex gap-1 justify-between">
          <div>
            {QuestionOptions.find(e => {
              return e.value === currentItem?.type
            })?.label}({currentItem?.score}分)
          </div>
          <h1 className="text-2xl">
            总分: {sumScore}
          </h1>
          <Button
            onClick={onPrev}
            disabled={current === 0}
          >
            上一题
          </Button>
          <Button
            onClick={onNext}
            disabled={current === list.flatMap(item => item.children).length - 1}
          >
            下一题
          </Button>
        </div>
        <PaperContext
          currentItem={currentItem}
          answers={answers}
          setAnswers={setAnswers}
          type={testType}
        />
      </div>
    </div>
  )
}
export default PaperCard